package com.lw.oop.daythree.edemo;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

/**
 * @author liuwei
 * @ClassName Test.java
 * @description: TODO
 * @date 2023年06月15日
 * @version: 1.0
 */
public class Test {
    public static void main(String[] args) throws Exception{
        Class a = Class.forName("com.mysql.jdbc.Driver");
        System.out.println(a.getClass());
        System.out.println(a.getName());
        System.out.println(a.getPackage());
        System.out.println(a.getInterfaces());
        System.out.println(a.getInterfaces().hashCode());
        System.out.println(a.getClassLoader());

        System.out.println("---------------------------------------------");
        //反射获取class第一种方法
        Class c = Class.forName("com.lw.oop.daythree.edemo.User");
        User user= (User)c.newInstance();
        user.setName("liuwei");
        System.out.println(user.toString());

        System.out.println("******************反射Fild-class方法********************");
        System.out.println("返回完整类名带包名"+c.getName());
        System.out.println("返回类名："+ c.getSimpleName());
        System.out.println("返回类中public修饰的属性名称："+ c.getFields());
        System.out.println("返回类中所有的属性 ："+ c.getDeclaredFields());
        System.out.println("返回属性名name获取指定的属性 ："+c.getDeclaredField("name"));
        System.out.println("获取属性的修饰符列表 ："+ c.getModifiers());
        System.out.println("返回类中所有的实例方法"+c.getDeclaredMethods());
        System.out.println("返回方法名为name和方法形参获取指定方法："+ c.getDeclaredMethod("name"));
        System.out.println("返回类中所有的实例方法 ："+c.getMethods());
        System.out.println("返回类中所有的构造方法"+ c.getDeclaredConstructors());
        System.out.println("指定方法参数的构造方法："+c.getConstructor(String.class, Integer.class));
        System.out.println("返回调用类的父类："+ c.getSuperclass());
        System.out.println("返回调用类实现的接口集合："+ c.getInterfaces());



        System.out.println("******************反射Fild-field类方法********************");

        Field[] fields = c.getFields();
        for (Field f: fields) {
            System.out.println(f.toString());
        }
        Field[] declaredFields = c.getDeclaredFields();
        for (Field f: declaredFields) {
            System.out.println(f.toString());
        }
        Field dec = c.getDeclaredField("age");
        Field dec1 = c.getDeclaredField("note");
        System.out.println("返回属性名："+fields[0].getName());
        System.out.println("返回该属性的修饰符："+fields[0].getModifiers());
        System.out.println("返回该属性的类型："+fields[0].getType());
        System.out.println("返回该属性是否是public修饰的："+fields[0].isAccessible());


        System.out.println("返回属性名："+declaredFields[2].getName());
        System.out.println("返回该属性的修饰符："+declaredFields[2].getModifiers());
        System.out.println("返回该属性的类型："+declaredFields[2].getType());
        System.out.println("返回该属性是否是public修饰的："+declaredFields[2].isAccessible());
        dec.set(user, 20);
        //打开属性Private限制
        dec1.setAccessible(true);
        dec1.set(user, "测试001");
        System.out.println("age="+user.age);
        System.out.println("note="+dec1.get(user));


        System.out.println("******************反射Method-Method方法*******");
        Method[] methods = c.getMethods();
        for (Method m: methods) {
            System.out.println(m);
        }
        // 获取Class的第一种方法
        Method m1 = c.getMethod("getAge");

        System.out.println("返回方法的名字："+m1.getName());
        System.out.println("返回该方法的返回类型："+m1.getReturnType());
        System.out.println("返回方法的参数类型："+ m1.getModifiers());
        System.out.println("返回该方法的所有参数类型："+m1.getParameterTypes());
        System.out.println("调用方法"+m1.invoke(user));

        System.out.println("*****************Construtor *******************");
        Constructor[] constructors = c.getConstructors();
        for (Constructor con: constructors) {
            System.out.println(con);
        }
        System.out.println("返回构造方法名："+ constructors[0].getName());
        System.out.println("返回该构造方法的修饰符："+constructors[0].getModifiers());
        System.out.println("返回该构造方法的参数类型："+constructors[0].getParameterTypes());
        System.out.println("返回该构造方法所在的类："+constructors[0].getDeclaringClass());
        Constructor constructor = constructors[0];
        if(constructor.getParameters().length == 0){
            User or = (User)constructors[0].newInstance();
            or.setName("123");
            System.out.println(or.toString());
        }else {
            System.out.println("错误");
        }


        System.out.println("*********************************************");
        //获取Class的第二种方法
        User u = new User();
        System.out.println(u.getClass());
        //获取 Class的第三种方法
        Class c1=Integer.class;
        Class c2=User.class;
        System.out.println(c1);
        System.out.println(c2);


    }
}
